home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / raytrace / radiance / nextrad.lha / NeXtRad / mesh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-22  |  16.8 KB  |  619 lines

  1. /* mesh.c */
  2. /* written by : Jason R. Wilson   2/21/93 */
  3.  
  4. /* provides routines for initial mesh generation and adaptive mesh generation */
  5.  
  6. #include "datastruct.h"
  7. #include <stdio.h>
  8. #include "hemicube.h"
  9.  
  10. VertexCell ***EdgeMatrix; /* needs to be global */
  11.  
  12. /* use an edge matrix */
  13.  
  14. float AdaptiveTol;
  15.  
  16. void initAdaptiveTol (double tol)
  17. {
  18.   AdaptiveTol = tol;
  19. }
  20.  
  21.  
  22. void SubDivide (ObjectCell *Object,int NumVertices)
  23. {
  24.  
  25. /* assume that vertices have been identified with IdentifyVertex */
  26.  
  27. int loop,loop2;
  28. PolygonCell *CurrentPoly,*temp;
  29. VertexListCell *CurrentVertList;
  30. VertexCell *a,*b,*c,*d;
  31. VertexCell *OldVertices[4];
  32. VertexCell *NewVertices[5];
  33. PolygonCell *NewPolyList;
  34. PolygonCell *NewPoly;
  35. PolygonListCell *CurrentPolyList;
  36. VertexCell *LocalVertices[4];
  37.  
  38. /* get mem. for edge matrix */
  39.  
  40. EdgeMatrix = (VertexCell ***)(malloc((NumVertices+1)*sizeof(VertexCell **)));
  41. for (loop = 0;loop < NumVertices + 1;loop++)
  42.   EdgeMatrix[loop] = (VertexCell **)(malloc((NumVertices+1)*sizeof(VertexCell *)));
  43.  
  44. /* init. edge matrix pointers to NULL */
  45.  
  46. for (loop = 0;loop <= NumVertices;loop++)
  47.   for (loop2 = 0;loop2 <= NumVertices;loop2++)
  48.     EdgeMatrix[loop][loop2] = NULL;
  49.  
  50. NewPolyList = NULL;
  51.  
  52. /* through each polygon and create 4 new vertices (one for each edge)
  53.    that will be used for the subdivision */
  54. /* use the edge matrix to prevent redundent vertices and preserve
  55.    topological info. */
  56.  
  57. CurrentPoly = Object->PolygonHead;
  58.  
  59. while (!(CurrentPoly == NULL))
  60.   {
  61.     /* init. d, the new center point of the polygon */
  62.     
  63.     d = (VertexCell *)(malloc(sizeof(VertexCell)));
  64.     InitVertexCell (d);
  65.     d->WorldPosition.x = 0.0;
  66.     d->WorldPosition.y = 0.0;
  67.     d->WorldPosition.z = 0.0;
  68.     
  69.     
  70.     CurrentVertList = CurrentPoly->Vertices;
  71.     for (loop = 0;loop < 4;loop++)
  72.       {
  73.     /* a and b are pointers the the two vertices currently being cons. */
  74.     a = CurrentVertList->Vertex;
  75.     if (loop == 3)
  76.       b = CurrentPoly->Vertices->Vertex;
  77.     else
  78.       b = CurrentVertList->Rest->Vertex;
  79.     
  80.     /* update old vertices array */
  81.     
  82.     OldVertices[loop] = a;
  83.     
  84.     /* update d, the center point */
  85.     
  86.     d->WorldPosition.x += a->WorldPosition.x;
  87.     d->WorldPosition.y += a->WorldPosition.y;
  88.     d->WorldPosition.z += a->WorldPosition.z;
  89.     
  90.     
  91.     if (EdgeMatrix[a->Number][b->Number] == NULL)
  92.       {
  93.         /* need to create new vertex, namely c */
  94.         c = (VertexCell *)(malloc(sizeof(VertexCell)));
  95.         InitVertexCell (c);
  96.         /* update edge matrix */
  97.         EdgeMatrix[a->Number][b->Number] = c;
  98.         EdgeMatrix[b->Number][a->Number] = c;
  99.         /* find position of c by averaging */
  100.         c->WorldPosition.x = (a->WorldPosition.x + b->WorldPosition.x)/2.0;
  101.         c->WorldPosition.y = (a->WorldPosition.y + b->WorldPosition.y)/2.0;
  102.         c->WorldPosition.z = (a->WorldPosition.z + b->WorldPosition.z)/2.0;
  103.         /* insert c into object vertex list */
  104.         c->Next = Object->VertexHead;
  105.         Object->VertexHead = c;
  106.       }
  107.     else
  108.       c = EdgeMatrix[a->Number][b->Number];
  109.     
  110.     NewVertices[loop] = c;
  111.     
  112.     CurrentVertList=CurrentVertList->Rest;
  113.       }
  114.     
  115.     /* average them */
  116.     d->WorldPosition.x /= 4.0;
  117.     d->WorldPosition.y /= 4.0;
  118.     d->WorldPosition.z /= 4.0;
  119.     
  120.     /* insert d into object vertex list */
  121.     d->Next = Object->VertexHead;
  122.     Object->VertexHead = d;
  123.     
  124.     
  125.     /* insert d into newvertex list */
  126.     NewVertices[4] = d;
  127.     
  128.     /* Next remove CurrentPoly from all of the old vertices */
  129.  
  130.     for (loop = 0;loop < 4;loop++)
  131.       {
  132.     CurrentPolyList = OldVertices[loop]->Polygons;
  133.     /* base case */
  134.     if (CurrentPolyList->Polygon == CurrentPoly)
  135.       {
  136.         OldVertices[loop]->Polygons = OldVertices[loop]->Polygons->Rest;
  137.       }
  138.     else 
  139.       {
  140.         while (!(CurrentPolyList->Rest->Polygon == CurrentPoly))
  141.           CurrentPolyList = CurrentPolyList->Rest;
  142.         CurrentPolyList->Rest = CurrentPolyList->Rest->Rest;
  143.       }
  144.       }
  145.     
  146.     /* now, create new polygons and add them to the beginning of 
  147.        the new polygons list */
  148.     
  149.     for (loop = 0;loop < 4;loop++)
  150.       {
  151.     LocalVertices[0] = OldVertices[loop];
  152.     LocalVertices[1] = NewVertices[loop];
  153.     LocalVertices[2] = NewVertices[4];
  154.     if (!(loop == 0))
  155.       LocalVertices[3] = NewVertices[loop-1];
  156.     else
  157.       LocalVertices[3] = NewVertices[3];
  158.     
  159.     /* create new poly and make it point to all of the vertices */
  160.     
  161.     NewPoly = (PolygonCell *)(malloc(sizeof(PolygonCell)));
  162.     InitPolygonCell (NewPoly);
  163.     NewPoly->Textured = CurrentPoly->Textured;
  164.     NewPoly->R.r = CurrentPoly->R.r;
  165.     NewPoly->R.g = CurrentPoly->R.g;
  166.     NewPoly->R.b = CurrentPoly->R.b;
  167.     NewPoly->E.r = CurrentPoly->E.r;
  168.     NewPoly->E.g = CurrentPoly->E.g;
  169.     NewPoly->E.b = CurrentPoly->E.b;
  170.     
  171.     
  172.     for (loop2 = 3;loop2 > -1 ;loop2--) /* reverse order to preserve order */
  173.       {
  174.         CurrentVertList = (VertexListCell *)(malloc(sizeof(VertexListCell)));
  175.         InitVertexListCell (CurrentVertList);
  176.         CurrentVertList->Vertex = LocalVertices[loop2];
  177.         CurrentVertList->Rest = NewPoly->Vertices;
  178.         NewPoly->Vertices = CurrentVertList;
  179.       }
  180.     
  181.     
  182.     /* go through and make all of the vertices point to the newpoly */
  183.     
  184.     for (loop2 = 0;loop2 < 4;loop2++)
  185.       {
  186.         CurrentPolyList =(PolygonListCell *)(malloc(sizeof(PolygonListCell)));
  187.         InitPolygonListCell (CurrentPolyList);
  188.         CurrentPolyList->Polygon = NewPoly;
  189.         CurrentPolyList->Rest = LocalVertices[loop2]->Polygons;
  190.         LocalVertices[loop2]->Polygons = CurrentPolyList;
  191.       }
  192.     
  193.     /* insert the new polygon into NewPolyList */
  194.     
  195.     NewPoly->Next = NewPolyList;
  196.     NewPolyList = NewPoly;
  197.     
  198.       }
  199.     temp = CurrentPoly; 
  200.     CurrentPoly = CurrentPoly->Next; /* process the next polygon */
  201.     free (temp);  /*   free up storage for old polygon */
  202.   }
  203. Object->PolygonHead = NewPolyList; /* replace the old poly 
  204.                       list with the new one */
  205.  
  206. /* free memory of EdgeMatrix */
  207.  
  208. for (loop = 0;loop < NumVertices + 1;loop++)
  209.   free (EdgeMatrix[loop]);
  210. free (EdgeMatrix);
  211.  
  212. }
  213.       
  214.      
  215. /*----------------------------------------------------------------------*/
  216.  
  217.  
  218. CreateNewElements (ObjectCell *Object,PolygonCell *CurrentPoly)
  219. /* recursively subdivide polygons with high gradients */
  220.  
  221. {
  222.  
  223. PolygonCell *NewPoly;
  224. VertexCell *OldVertices[4];
  225. VertexCell *NewVertices[5];
  226. VertexCell *LocalVertices[4];
  227. VertexCell *a,*b,*c,*d;
  228. int loop,loop2;
  229. PolygonListCell *CurrentPolyList;
  230. VertexListCell *CurrentVertList;
  231.  
  232.  
  233. printf ("subdivision necessary \n");
  234. /* subdivision necessary, create 4 new polygons, and 5 new vertices */
  235.     
  236. /*******************************************************************/
  237.  
  238. /* init. d, the new center point of the polygon */
  239.  
  240. d = (VertexCell *)(malloc(sizeof(VertexCell)));
  241. InitVertexCell (d);
  242. d->WorldPosition.x = 0.0;
  243. d->WorldPosition.y = 0.0;
  244. d->WorldPosition.z = 0.0;
  245.  
  246. CurrentVertList = CurrentPoly->Vertices;
  247. for (loop = 0;loop < 4;loop++)
  248.   {
  249.     /* a and b are pointers the the two vertices currently being considered. */
  250.     
  251.     a = CurrentVertList->Vertex;
  252.     if (loop == 3)
  253.       b = CurrentPoly->Vertices->Vertex;
  254.     else
  255.       b = CurrentVertList->Rest->Vertex;
  256.     
  257.     /* update old vertices array */
  258.     
  259.     OldVertices[loop] = a;
  260.     
  261.     /* update d, the center point */
  262.     
  263.     d->WorldPosition.x += a->WorldPosition.x;
  264.     d->WorldPosition.y += a->WorldPosition.y;
  265.     d->WorldPosition.z += a->WorldPosition.z;
  266.     
  267.     if (EdgeMatrix[a->Number][b->Number] == NULL)
  268.       { 
  269.     /* need to create new vertex, namely c */
  270.     c = (VertexCell *)(malloc(sizeof(VertexCell)));
  271.     InitVertexCell (c);
  272.     /* update edge matrix */
  273.     EdgeMatrix[a->Number][b->Number] = c;
  274.     EdgeMatrix[b->Number][a->Number] = c;
  275.     /* find position of c by averaging */
  276.     c->WorldPosition.x = (a->WorldPosition.x + b->WorldPosition.x)/2.0;
  277.     c->WorldPosition.y = (a->WorldPosition.y + b->WorldPosition.y)/2.0;
  278.     c->WorldPosition.z = (a->WorldPosition.z + b->WorldPosition.z)/2.0;
  279.     /* insert c into object vertex list */
  280.     c->Next = Object->VertexHead;
  281.     Object->VertexHead = c;
  282.       }
  283.     else
  284.       c = EdgeMatrix[a->Number][b->Number];
  285.     
  286.     NewVertices[loop] = c;
  287.     
  288.     CurrentVertList=CurrentVertList->Rest;
  289.   }
  290.  
  291. /* average them */
  292. d->WorldPosition.x /= 4.0;
  293. d->WorldPosition.y /= 4.0;
  294. d->WorldPosition.z /= 4.0;
  295.  
  296. /* insert d into object vertex list */
  297. d->Next = Object->VertexHead;
  298. Object->VertexHead = d;
  299.  
  300. /* insert d into newvertex list */
  301. NewVertices[4] = d;
  302.  
  303.  
  304. /******************************************************************/
  305. /* Next remove CurrentPoly from all of the old vertices */
  306.  
  307. for (loop = 0;loop < 4;loop++)
  308.   {
  309.     CurrentPolyList = OldVertices[loop]->Polygons;
  310.     /* base case */
  311.     if (CurrentPolyList->Polygon == CurrentPoly)
  312.       {
  313.     OldVertices[loop]->Polygons = OldVertices[loop]->Polygons->Rest;
  314.       }
  315.     else 
  316.       {
  317.     while (!(CurrentPolyList->Rest->Polygon == CurrentPoly))
  318.       CurrentPolyList = CurrentPolyList->Rest;
  319.     CurrentPolyList->Rest = CurrentPolyList->Rest->Rest;
  320.       }
  321.   }
  322.  
  323. /********************************************************************/
  324.  
  325. /* now, create new polygons and add them to the beginning of 
  326.    the new polygons list */
  327.  
  328. for (loop = 0;loop < 4;loop++)
  329.   {
  330.     LocalVertices[0] = OldVertices[loop];
  331.     LocalVertices[1] = NewVertices[loop];
  332.     LocalVertices[2] = NewVertices[4];
  333.     if (!(loop == 0))
  334.       LocalVertices[3] = NewVertices[loop-1];
  335.     else
  336.       LocalVertices[3] = NewVertices[3];
  337.     
  338.     /* create new poly and make it point to all of the vertices */
  339.     
  340.     NewPoly = (PolygonCell *)(malloc(sizeof(PolygonCell)));
  341.     InitPolygonCell (NewPoly);
  342.     NewPoly->Textured = CurrentPoly->Textured;
  343.     NewPoly->R.r = CurrentPoly->R.r;
  344.     NewPoly->R.g = CurrentPoly->R.g;
  345.     NewPoly->R.b = CurrentPoly->R.b;
  346.     NewPoly->E.r = CurrentPoly->E.r;
  347.     NewPoly->E.g = CurrentPoly->E.g;
  348.     NewPoly->E.b = CurrentPoly->E.b;
  349.     NewPoly->Normal = CurrentPoly->Normal;
  350.     
  351.     for (loop2 = 3;loop2 > -1 ;loop2--) /* reverse order to preserve order */
  352.       {
  353.     CurrentVertList = (VertexListCell *)(malloc(sizeof(VertexListCell)));
  354.     InitVertexListCell (CurrentVertList);
  355.     CurrentVertList->Vertex = LocalVertices[loop2];
  356.     CurrentVertList->Rest = NewPoly->Vertices;
  357.     NewPoly->Vertices = CurrentVertList;
  358.       }
  359.     
  360.     
  361.     /* go through and make all of the vertices point to the newpoly */
  362.     
  363.     for (loop2 = 0;loop2 < 4;loop2++)
  364.       {
  365.     CurrentPolyList =(PolygonListCell *)(malloc(sizeof(PolygonListCell)));
  366.     InitPolygonListCell (CurrentPolyList);
  367.     CurrentPolyList->Polygon = NewPoly;
  368.     CurrentPolyList->Rest = LocalVertices[loop2]->Polygons;
  369.     LocalVertices[loop2]->Polygons = CurrentPolyList;
  370.       }
  371.     
  372.     /* insert the new polygon into NewPolyList */
  373.     
  374.     CurrentPoly->Subs[loop] = NewPoly;
  375.       
  376.   }
  377. }
  378.  
  379. /************************************************************/
  380.  
  381. FixTVertices (PolygonCell *CurrentPoly)
  382. {
  383.   VertexListCell *traverse,*CurrentVertList;
  384.   PolygonListCell *CurrentPolyList;
  385.   VertexCell *a,*b;
  386.  
  387.   if (!(CurrentPoly->Subs[0] == NULL))
  388.     {
  389.       FixTVertices (CurrentPoly->Subs[0]);
  390.       FixTVertices (CurrentPoly->Subs[1]);
  391.       FixTVertices (CurrentPoly->Subs[2]);
  392.       FixTVertices (CurrentPoly->Subs[3]);
  393.     }
  394.   else
  395.     {
  396.       traverse = CurrentPoly->Vertices;
  397.       while (!(traverse == NULL))
  398.     {
  399.       a = traverse->Vertex;
  400.       if (traverse->Rest == NULL)
  401.         b = CurrentPoly->Vertices->Vertex;
  402.       else
  403.         b = traverse->Rest->Vertex;
  404.       if (EdgeMatrix[a->Number][b->Number] == NULL)
  405.         traverse = traverse->Rest;
  406.       else
  407.         {
  408.           CurrentVertList = (VertexListCell *)(malloc(sizeof(VertexListCell)));
  409.           InitVertexListCell (CurrentVertList);
  410.           CurrentVertList->Vertex = EdgeMatrix[a->Number][b->Number];
  411.           CurrentPolyList = (PolygonListCell *)(malloc(sizeof(PolygonListCell)));
  412.           InitPolygonListCell (CurrentPolyList);
  413.           CurrentPolyList->Polygon = CurrentPoly;
  414.           CurrentPolyList->Rest = CurrentVertList->Vertex->Polygons;
  415.           CurrentVertList->Vertex->Polygons = CurrentPolyList;
  416.           CurrentVertList->Rest = traverse->Rest;
  417.           traverse->Rest = CurrentVertList;
  418.           traverse = CurrentVertList->Rest;
  419.         }
  420.     }
  421.     }
  422. }
  423.  
  424. /***********************************************************************/
  425.  
  426. FindSmallest (ObjectCell *Object,PolygonCell *Poly,int NumPolys)
  427. {
  428.   Color total;  /* used to compute average */
  429.   Boolean MustDivide;
  430.   int count;
  431.   VertexListCell *traverse;
  432.   double *row;
  433.   int loop,loop2;
  434.   PolygonCell *Poly2;
  435.   ObjectCell *Object2;
  436.  
  437.  
  438.   /* make space for row */
  439.   
  440.   row = (double *)(malloc(sizeof(double)*NumPolys));
  441.  
  442.   
  443.   if (Poly->Subs[0] == NULL)
  444.     {
  445.       /******************************************/
  446.       /* go through vertex intensities grouped  */
  447.       /* by pnolys...                            */
  448.       /******************************************/
  449.       
  450.       traverse = Poly->Vertices;
  451.       total.r = 0.0;
  452.       total.g = 0.0;
  453.       total.b = 0.0;
  454.       count = 0;
  455.       while (!(traverse == NULL))
  456.     {
  457.       count++;
  458.       total.r += traverse->Vertex->B.r;
  459.       total.g += traverse->Vertex->B.g;
  460.       total.b += traverse->Vertex->B.b;     
  461.       traverse = traverse->Rest;
  462.     }
  463.       total.r = total.r/(double)count;
  464.       total.g = total.g/(double)count;
  465.       total.b = total.b/(double)count;
  466.       /* test for wide variances from average */
  467.       MustDivide = false;
  468.       if (count == 4)
  469.     {
  470.       traverse = Poly->Vertices;
  471.       while (!(traverse == NULL))
  472.         {
  473.           if ((((traverse->Vertex->B.r - total.r)/total.r) > AdaptiveTol) ||
  474.           (((traverse->Vertex->B.r - total.r)/total.r) < -1.0*AdaptiveTol))
  475.         MustDivide = true;
  476.           traverse = traverse->Rest;
  477.         }
  478.       traverse = Poly->Vertices;
  479.       while (!(traverse == NULL))
  480.         {
  481.           if ((((traverse->Vertex->B.g - total.g)/total.g) > AdaptiveTol) ||
  482.           (((traverse->Vertex->B.g - total.g)/total.g) < -1.0*AdaptiveTol))
  483.         MustDivide = true;
  484.           traverse = traverse->Rest;
  485.         }
  486.       traverse = Poly->Vertices;
  487.       while (!(traverse == NULL))
  488.         {
  489.           if ((((traverse->Vertex->B.b - total.b)/total.b) > AdaptiveTol) ||
  490.           (((traverse->Vertex->B.b - total.b)/total.b) < -1.0*AdaptiveTol))
  491.         MustDivide = true;
  492.           traverse = traverse->Rest;
  493.         }
  494.     }
  495.       if (MustDivide == true)
  496.     {
  497.       CreateNewElements (Object,Poly);
  498.       for (loop = 0;loop < 4;loop++)
  499.         {
  500.           for (loop2 = 0;loop2 < NumPolys;loop2++) /* init. row */
  501.         row[loop2] = 0;          
  502.           ProjectPatch(Poly->Subs[loop],row);
  503.           Poly->Subs[loop]->B = Poly->Subs[loop]->E;
  504.           Object2 = ObjectHead;   
  505.           Poly2 = ObjectHead->PolygonHead;
  506.           for (loop2 = 0;loop2 < NumPolys;loop2++)
  507.         {
  508.           Poly->Subs[loop]->B.r += Poly->Subs[loop]->R.r*row[loop2]*Poly2->B.r;
  509.           Poly->Subs[loop]->B.g += Poly->Subs[loop]->R.g*row[loop2]*Poly2->B.g;
  510.           Poly->Subs[loop]->B.b += Poly->Subs[loop]->R.b*row[loop2]*Poly2->B.b;
  511.           /* advance the poly pointer */
  512.           
  513.           if ((Poly2->Next == NULL) && (!(Object2->Next == NULL)))
  514.             {
  515.               Object2 = Object2->Next;
  516.               Poly2 = Object2->PolygonHead;
  517.             }
  518.           else 
  519.             Poly2 = Poly2->Next;               
  520.         }
  521.           
  522.         }
  523.     }
  524.     }
  525.   else
  526.     {
  527.       FindSmallest(Object,Poly->Subs[0],NumPolys);
  528.       FindSmallest(Object,Poly->Subs[1],NumPolys);
  529.       FindSmallest(Object,Poly->Subs[2],NumPolys);
  530.       FindSmallest(Object,Poly->Subs[3],NumPolys);
  531.     }
  532.   free (row); /* free up row space */
  533. }
  534.  
  535.   
  536. SubdivideObjects (ObjectCell *Object,int NumVertices,int NumPolys)
  537.      /* subdivide polygons with high gradients (4-sided) */
  538. {
  539.   int loop,loop2;
  540.   PolygonCell *Poly,*CurrentPoly;
  541.   int count;
  542.   VertexCell *CurrentVert;
  543.   PolygonListCell *CurrentListPoly;
  544.   
  545.   /* get memory for adjacency matrix */
  546.   /* are we throwing enough pointers around yet? */
  547.   
  548.   EdgeMatrix = (VertexCell ***)(malloc((NumVertices+1)*sizeof(VertexCell **)));
  549.   for (loop = 0;loop < NumVertices + 1;loop++)
  550.     EdgeMatrix[loop] = (VertexCell **)(malloc((NumVertices+1)*sizeof(VertexCell *)));
  551.   
  552.   /* init. edge matrix pointers to NULL */
  553.   
  554.   for (loop = 0;loop <= NumVertices;loop++)
  555.     for (loop2 = 0;loop2 <= NumVertices;loop2++)
  556.       EdgeMatrix[loop][loop2] = NULL;
  557.   
  558.   Poly = Object->PolygonHead;
  559.   while (!(Poly == NULL))
  560.     {    
  561.       FindSmallest (Object,Poly,NumPolys);
  562.       Poly = Poly->Next;     
  563.     }
  564.   
  565.   /* now, connect connect the t-vertices by adding vertices
  566.      to polygons that have not been subdivided */
  567.   
  568.   CurrentPoly = Object->PolygonHead;
  569.   while (!(CurrentPoly == NULL))
  570.     {
  571.       FixTVertices (CurrentPoly);
  572.       CurrentPoly = CurrentPoly->Next;
  573.     }
  574.   
  575.   /* move radiosities from patches to vertices */
  576.   
  577.   
  578.   CurrentVert = Object->VertexHead;
  579.   while (!(CurrentVert == NULL))
  580.     {
  581.       CurrentVert->B.r = 0.0;
  582.       CurrentVert->B.g = 0.0;
  583.       CurrentVert->B.b = 0.0;
  584.       count = 0;
  585.       CurrentListPoly = CurrentVert->Polygons;
  586.       while (!(CurrentListPoly == NULL))
  587.     {
  588.       count++;
  589.       CurrentVert->B.r += CurrentListPoly->Polygon->B.r;
  590.       CurrentVert->B.g += CurrentListPoly->Polygon->B.g;
  591.       CurrentVert->B.b += CurrentListPoly->Polygon->B.b;
  592.       CurrentListPoly = CurrentListPoly->Rest;
  593.     }
  594.       CurrentVert->B.r /= (double)count;
  595.       CurrentVert->B.g /= (double)count;
  596.       CurrentVert->B.b /= (double)count;
  597.       
  598.       
  599.       CurrentVert = CurrentVert->Next;
  600.     }
  601.   
  602.   /* free memory of EdgeMatrix */
  603.  
  604.   for (loop = 0;loop < NumVertices + 1;loop++)
  605.     free (EdgeMatrix[loop]);
  606.   free (EdgeMatrix);
  607.   
  608. }
  609.  
  610.  
  611.       
  612.       
  613.       
  614.       
  615.    
  616.  
  617.  
  618.  
  619.